package com.faithbj.controller.infoInput;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.annotation.Resource;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.krysalis.barcode4j.BarcodeException;
import org.krysalis.barcode4j.BarcodeGenerator;
import org.krysalis.barcode4j.BarcodeUtil;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.MimeTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.faithbj.common.utils.SystemConfigUtil;
import com.faithbj.common.web.controller.BaseController;

@Controller
@RequestMapping
public class BarcodeController extends BaseController {

	private static final long serialVersionUID = 9068281894134828427L;

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private SystemConfigUtil systemConfigUtil;

	/**
	 * 以PNG格式输出验证码
	 * 
	 * @param code
	 * @return
	 */
	@RequestMapping(value = "/barcode/{code}")
	public ResponseEntity<byte[]> barcode(@PathVariable("code") String code) {
		HttpHeaders headers = new HttpHeaders();
		headers.add("Content-Type", MediaType.IMAGE_PNG_VALUE);

		ByteArrayOutputStream bout = new ByteArrayOutputStream();

		int orientation = 0;// 方向，0是横向的

		Configuration cfg = buildCfg(null, null, null, null, null, null, null,
				null);

		if (code == null) {
			code = "0123456789abcdedf";
		}

		BarcodeUtil util = BarcodeUtil.getInstance();
		BarcodeGenerator gen = null;

		try {
			gen = util.createBarcodeGenerator(cfg);
			Integer resText = systemConfigUtil.getResText();// 获取分辨率
			int resolution = 300; // dpi
			if (null != resText) {
				resolution = resText;
			}
			if (resolution > 2400) {
				throw new IllegalArgumentException(
						"Resolutions above 2400dpi are not allowed");
			}
			if (resolution < 10) {
				throw new IllegalArgumentException(
						"Minimum resolution must be 10dpi");
			}

			BitmapCanvasProvider canvas = new BitmapCanvasProvider(bout,
					MimeTypes.MIME_PNG, resolution,
					BufferedImage.TYPE_BYTE_BINARY, true, orientation);
			gen.generateBarcode(canvas, code);
			canvas.finish();
			bout.close();
		} catch (IOException e) {
			logger.error("生成条形码IO错误！", e.getMessage());
		} catch (ConfigurationException e) {
			logger.error("生成条形码配置错误！", e.getMessage());
		} catch (BarcodeException e) {
			logger.error("生成条形码错误！", e.getMessage());
		}

		return new ResponseEntity<byte[]>(bout.toByteArray(), headers,
				HttpStatus.OK);
	}

	/**
	 * 使用code128
	 * 
	 * @param height
	 *            高
	 * @param moduleWidth
	 *            模块宽度
	 * @param wideFactor
	 *            宽度因子
	 * @param quietZone
	 *            静态域
	 * @param humanReadablePosition
	 *            可读占位符
	 * @param pattern
	 *            样式
	 * @param humanReadableSize
	 *            字体大小
	 * @param humanReadableFont
	 *            字体Family
	 * @return
	 */
	protected Configuration buildCfg(String height, String moduleWidth,
			String wideFactor, String quietZone, String humanReadablePosition,
			String pattern, String humanReadableSize, String humanReadableFont) {
		DefaultConfiguration cfg = new DefaultConfiguration("barcode");
		// Get type
		String type = "code128";

		DefaultConfiguration child = new DefaultConfiguration(type);
		cfg.addChild(child);
		// 获取一些附加属性，比如长、宽、高
		DefaultConfiguration attr;
		if (height != null) {
			attr = new DefaultConfiguration("height");
			attr.setValue(height);
			child.addChild(attr);
		}

		if (moduleWidth != null) {
			attr = new DefaultConfiguration("module-width");
			attr.setValue(moduleWidth);
			child.addChild(attr);
		}

		if (wideFactor != null) {
			attr = new DefaultConfiguration("wide-factor");
			attr.setValue(wideFactor);
			child.addChild(attr);
		}

		if (quietZone != null) {
			attr = new DefaultConfiguration("quiet-zone");
			if (quietZone.startsWith("disable")) {
				attr.setAttribute("enabled", "false");
			} else {
				attr.setValue(quietZone);
			}
			child.addChild(attr);
		}

		if (!((humanReadablePosition == null) && (pattern == null)
				&& (humanReadableSize == null) && (humanReadableFont == null))) {
			attr = new DefaultConfiguration("human-readable");

			DefaultConfiguration subAttr;
			if (pattern != null) {
				subAttr = new DefaultConfiguration("pattern");
				subAttr.setValue(pattern);
				attr.addChild(subAttr);
			}
			if (humanReadableSize != null) {
				subAttr = new DefaultConfiguration("font-size");
				subAttr.setValue(humanReadableSize);
				attr.addChild(subAttr);
			}
			if (humanReadableFont != null) {
				subAttr = new DefaultConfiguration("font-name");
				subAttr.setValue(humanReadableFont);
				attr.addChild(subAttr);
			}
			if (humanReadablePosition != null) {
				subAttr = new DefaultConfiguration("placement");
				subAttr.setValue(humanReadablePosition);
				attr.addChild(subAttr);
			}

			child.addChild(attr);
		}

		return cfg;
	}

}
